package com.wenx.v3system.modular.cloud.domain.dto;

import com.wenx.anno.FieldPermission;
import com.wenx.base.domain.BaseDto;
import com.wenx.v3core.anoo.DataMask;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import java.util.List;

/**
 * 系统用户DTO
 */
@EqualsAndHashCode(callSuper = true)
@Data
@Schema(description = "系统用户信息")
public class SysUserDto extends BaseDto {


    /**
     * 用户名 - 公开字段
     */
    @NotBlank(message = "用户名不能为空")
    @Size(max = 50, message = "用户名长度不能超过50个字符")
    @Schema(description = "用户名", example = "测试用户")
    private String username;

    /**
     * 真实姓名 - 公开字段
     */
    @Size(max = 50, message = "真实姓名长度不能超过50个字符")
    @Schema(description = "真实姓名", example = "张三")
    private String realName;

    /**
     * 密码 - 高度敏感字段，只有超级管理员可见
     */
    @FieldPermission(
        level = FieldPermission.AccessLevel.CONFIDENTIAL,
        description = "密码只有超级管理员可以查看"
    )
    @Size(min = 6, max = 100, message = "密码长度必须在6-100个字符之间")
    @Schema(description = "密码", example = "123456")
    @DataMask(strategy = DataMask.MaskStrategy.PASSWORD)
    private String password;

    /**
     * 用户状态 - 普通字段
     */
    @Schema(description = "用户状态：1-启用，0-禁用，2-锁定", example = "1")
    private Integer status;

    /**
     * 邮箱 - 敏感信息，需要权限控制
     */
    @FieldPermission(
        value = {"user:read"},
        level = FieldPermission.AccessLevel.PROTECTED,
        condition = "user.id == target.id || user.departmentId == target.departmentId",
        description = "邮箱只能查看本人或同部门的"
    )
    @Email(message = "邮箱格式不正确")
    @Schema(description = "邮箱", example = "test@example.com")
    @DataMask(strategy = DataMask.MaskStrategy.EMAIL)
    private String email;

    /**
     * 手机号 - 敏感信息，需要权限控制
     */
    @FieldPermission(
        value = {"user:read"},
        level = FieldPermission.AccessLevel.PRIVATE,
        condition = "user.id == target.id || user.departmentId == target.departmentId",
        description = "手机号只能查看本人或同部门的"
    )
    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
    @Schema(description = "手机号", example = "13888888888")
    @DataMask(strategy = DataMask.MaskStrategy.PHONE)
    private String phone;

    /**
     * 头像地址 - 公开字段
     */
    @Schema(description = "头像地址", example = "/avatar/user.jpg")
    private String avatar;

    /**
     * 性别 - 普通字段
     */
    @Schema(description = "性别：1-男，2-女，0-未知", example = "1")
    private Integer gender;

    /**
     * 年龄 - 普通字段
     */
    @Schema(description = "年龄", example = "25")
    private Integer age;

    /**
     * 个人描述 - 私有信息
     */
    @FieldPermission(
        level = FieldPermission.AccessLevel.PRIVATE,
        condition = "user.id == target.id",
        description = "个人描述只能查看本人的"
    )
    @Size(max = 500, message = "描述长度不能超过500个字符")
    @Schema(description = "个人描述", example = "这是一个测试用户")
    private String description;

    // 关联关系 - 大部分保持简单，只对敏感的权限信息进行控制
    @Schema(description = "用户角色列表")
    private List<SysRoleDto> roles;

    @Schema(description = "用户团队列表")
    private List<SysTeamDto> teams;

    @Schema(description = "用户部门列表")
    private List<SysDepartmentDto> departments;

    // 简化引用对象列表，用于兼容前端数据格式
    @Schema(description = "简化角色引用列表（兼容前端数据格式）")
    private List<SimpleReference> simpleRoles;

    @Schema(description = "简化团队引用列表（兼容前端数据格式）")
    private List<SimpleReference> simpleTeams;

    @Schema(description = "简化部门引用列表（兼容前端数据格式）")
    private List<SimpleReference> simpleDepartments;

    /**
     * 用户权限列表 - 敏感信息，需要高级权限
     */
    @FieldPermission(
        value = {"permission:read"},
        level = FieldPermission.AccessLevel.CONFIDENTIAL,
        description = "用户权限列表只有权限管理员可以查看"
    )
    @Schema(description = "用户权限列表")
    private List<SysPermissionDto> permissions;

    @Schema(description = "用户菜单列表")
    private List<SysMenuDto> menus;
    
    /**
     * 简化引用对象，用于兼容前端数据格式
     */
    @Data
    public static class SimpleReference {
        private String id;
        private String name;
        
        // 添加getter/setter以确保Jackson能正确序列化/反序列化
        public String getId() {
            return id;
        }
        
        public void setId(String id) {
            this.id = id;
        }
        
        public String getName() {
            return name;
        }
        
        public void setName(String name) {
            this.name = name;
        }
    }
}